package cn.kgc.shiro02.service.impl;

import cn.kgc.shiro02.commons.CodeMsg;
import cn.kgc.shiro02.commons.ResponseResult;
import cn.kgc.shiro02.dto.UserFormDTO;
import cn.kgc.shiro02.dto.UserPageDTO;
import cn.kgc.shiro02.entity.*;
import cn.kgc.shiro02.mapper.*;
import cn.kgc.shiro02.service.UserService;
import cn.kgc.shiro02.utils.SaltUtil;
import cn.kgc.shiro02.utils.TreeUtil;
import cn.kgc.shiro02.vo.PermissionVO;
import cn.kgc.shiro02.vo.UserVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{

    @Autowired(required = false)
    private UserMapper userMapper;

    @Autowired(required = false)
    private UserRoleMapper userRoleMapper;

    @Autowired(required = false)
    private RoleMapper roleMapper;

    @Autowired
    private RolePersMapper rolePersMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public ResponseResult selectPage(UserPageDTO userPageDTO) {

        Integer page = userPageDTO.getPage();
        Integer limit = userPageDTO.getLimit();

        String username = userPageDTO.getUsername();
        String city = userPageDTO.getCity();

        Page<User> userPage = new Page<>(page, limit);
        LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
        //是否是搜索 username!=null   city!=null  where username = ?  and  city = ?
        lambda.eq((username!=null&&!"".equals(username)), User::getUsername,username)
        .eq((city!=null&&!"".equals(city)), User::getCity,city);

        // 1.user表
        userMapper.selectPage(userPage,lambda);
        // 2.角色表  username  角色
        List<User> users = userPage.getRecords();
        long total = userPage.getTotal();

        //3.  userPageVO
        List<UserVO> userVOS = users.stream().map(user -> {
            UserVO userVO = new UserVO();
            // 拷贝实体类   user  -> userVo
            BeanUtils.copyProperties(user, userVO);
            Integer userId = user.getId();

            LambdaQueryWrapper<UserRole> lambda1 = new QueryWrapper<UserRole>().lambda();
            lambda1.eq(UserRole::getUserId,userId);
            List<UserRole> userRoles = userRoleMapper.selectList(lambda1);

            List<Integer> roleIds = userRoles.stream().map(userRole -> userRole.getRoleId()).collect(Collectors.toList());
            List<Role> roles = roleMapper.selectBatchIds(roleIds);

            List<String> roleNames = roles.stream().map(role -> role.getComments()).collect(Collectors.toList());

            userVO.setRoles(roleNames);
            return userVO;
        }).collect(Collectors.toList());

        //4. ResponseResult
        return new ResponseResult(CodeMsg.SUCCESS,total,userVOS);
    }

    @Override
    public ResponseResult saveUser(UserFormDTO userFormDTO) {


        // 1.保存用户信息到 user
        User user = new User();
        BeanUtils.copyProperties(userFormDTO, user);
        //判定用户是否存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", user.getUsername());
        User usr = userMapper.selectOne(userQueryWrapper);

        if(usr!=null){  // 用户已存在
            return  new ResponseResult(CodeMsg.USER_HAS_EXIST);
        }

        // 生成用户的默认密码 同时实现md5加密  加密+随机加盐  散列多次
        String salt = SaltUtil.getSalt(8);
        Md5Hash md5Hash = new Md5Hash("888888", salt,20);
        String s = md5Hash.toHex();

        user.setPassword(s);
        user.setSalt(salt);
        userMapper.insert(user);

        // 2.保存用户角色信息到user_role  user_id  role_id
        Integer userId = user.getId();
        List<Integer> roleIds = userFormDTO.getRoleIds();
        roleIds.stream().forEach(roleId->{
            UserRole userRole = new UserRole();
            userRole.setRoleId(roleId);
            userRole.setUserId(userId);
            userRoleMapper.insert(userRole);
        });

        return new ResponseResult(CodeMsg.SUCCESS);
    }

    @Override
    public ResponseResult selectById(Integer id) {

        User user = userMapper.selectById(id);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        LambdaQueryWrapper<UserRole> lambda = new QueryWrapper<UserRole>().lambda();
        lambda.eq(UserRole::getUserId,id);
        List<UserRole> userRoles = userRoleMapper.selectList(lambda);
        List<Integer> roleIds = userRoles.stream().map(userRole -> userRole.getRoleId()).collect(Collectors.toList());
        userVO.setRoleIds(roleIds);

        return new ResponseResult(CodeMsg.SUCCESS,null,userVO);
    }

    @Override
    public ResponseResult updateUser(UserFormDTO userFormDTO) {

        // 1.更新用户表
        User user = new User();
        BeanUtils.copyProperties(userFormDTO, user);
        userMapper.updateById(user);

        // 2.更新用户角色关联表
        Integer userId = user.getId();
        List<Integer> roleIds = userFormDTO.getRoleIds();

        // 删除当前用户拥有的角色id
        LambdaQueryWrapper<UserRole> lambda = new QueryWrapper<UserRole>().lambda();
        lambda.eq(UserRole::getUserId,userId);
        userRoleMapper.delete(lambda);

        roleIds.stream().forEach(roleId->{
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            // 添加用户的最新角色id
            userRoleMapper.insert(userRole);
        });

        return new ResponseResult(CodeMsg.SUCCESS);
    }

    @Override
    public ResponseResult deleteMore(Integer[] ids) {

        List<Integer> userIds = Arrays.asList(ids);

        //1.删除用户表中的信息
        userMapper.deleteBatchIds(userIds);
        // 2.删除用户角色关联表中的信息
        LambdaQueryWrapper<UserRole> lambda = new QueryWrapper<UserRole>().lambda();
        lambda.in(UserRole::getUserId,userIds);
        userRoleMapper.delete(lambda);
        return new ResponseResult(CodeMsg.SUCCESS);
    }

    @Override
    public Map<String, Object> loadMenu(String username) {

        // 最终返回的数据
        Map<String, Object> menu = new HashMap<>(16);


        // 主页信息
        Map<String,Object> home = new HashMap<>(16);
        home.put("title", "首页");
        home.put("href", "https://www.8zt.cc");
        menu.put("homeInfo",home);
        // logo 信息
        Map<String,Object> logo = new HashMap<>(16);
        logo.put("title","KGC后台");
        logo.put("image","/dist/images/logo.png");
        logo.put("href","http://www.kgc.com");
        /*
        *{
        *  "homeInfo":{
        *   title: "首页"
        *   href:"https://www.8zt.cc"
        *  },
        *
        * "logoInfo":{
        *   "title":"KGC后台",
        *   "image":"/dist/images/logo.png",
        *   "href":"http://www.kgc.com"
        *  }
        * }
        *
        * */
        menu.put("logoInfo",logo);


        // 1.根据用户名  查询用户id
        LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
        lambda.eq(User::getUsername,username);
        User user = userMapper.selectOne(lambda);
        Integer userId = user.getId();

        // 2.根据用户id 查询用户具有的角色id
        LambdaQueryWrapper<UserRole> lambda1 = new QueryWrapper<UserRole>().lambda();
        lambda1.eq(UserRole::getUserId,userId);
        List<UserRole> userRoles = userRoleMapper.selectList(lambda1);
        List<Integer> roleIds = userRoles.stream().map(userRole -> userRole.getRoleId()).collect(Collectors.toList());

        // 3.根据用户角色id   查询权限id   角色权限关联表
        LambdaQueryWrapper<RolePers> lambda2 = new QueryWrapper<RolePers>().lambda();
        lambda2.in(RolePers::getRoleId,roleIds);
        List<RolePers> rolePers = rolePersMapper.selectList(lambda2);

        if(rolePers.size()==0){
            return  menu;
        }

        List<Integer> perIds = rolePers.stream().map(rolePer -> rolePer.getPerId()).collect(Collectors.toList());
        //4.根据权限id  查询权限列表   按钮级别权限
        List<Permission> permissions = permissionMapper.selectBatchIds(perIds)
                .stream()
                .filter(permission -> permission.getIsMenu() != 2).collect(Collectors.toList());;

        // 5.将列表中Permission类型的数据 转换成 PermissionVO  List  child
        List<PermissionVO> collect = permissions.stream().map(permission -> {
            PermissionVO permissionVO = new PermissionVO();
            BeanUtils.copyProperties(permission, permissionVO);
            return permissionVO;
        }).collect(Collectors.toList());

        // 6.将装换完成的数据 传入工具类实现数据的挂载 treeUtil   List<PermissionVO>
        List<PermissionVO> permissionVOS = TreeUtil.toTree(collect, 0);
        //7.将挂载好的集合存入   map
        menu.put("menuInfo", permissionVOS);
        return menu;
    }
}




